package com.ijiuchuang.jc_localization.model.settings;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

import com.ijiuchuang.jc_localization.app.Config;
import com.ijiuchuang.jc_localization.bean.lite.Map;
import com.ijiuchuang.jc_localization.bean.lite.Setts;
import com.ijiuchuang.jc_localization.bean.lite.Station;
import com.ijiuchuang.jc_localization.contract.settings.SettsMapDetailContract;
import com.ijiuchuang.jc_localization.tools.utils.Log;
import com.ijiuchuang.jc_localization.tools.utils.Toastor;
import com.litesuits.orm.LiteOrm;
import com.litesuits.orm.db.assit.QueryBuilder;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import rx.Observable;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.functions.Func1;
import rx.schedulers.Schedulers;

/**
 * Created by Veev on 2016/6/20
 *
 * @link 384506557@qq.com
 */
public class SettsMapDetailModel implements SettsMapDetailContract.Model {

    private LiteOrm liteOrm = Config.liteOrm;

    @Override
    public void getMapsList(final Context context, Action1<String[]> action1) {
        Observable
                .create(new Observable.OnSubscribe<String[]>() {
                    @Override
                    public void call(Subscriber<? super String[]> subscriber) {
                        try {
                            String fileNames[] = context.getAssets().list("image/map");
                            subscriber.onNext(fileNames);
                        } catch (IOException e) {
                            e.printStackTrace();
                            subscriber.onError(e);
                        }
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(action1);
    }

    @Override
    public void getMapBitmap(final Context context, final int position, Action1<Bitmap> action1) {
        Observable
                .create(new Observable.OnSubscribe<Bitmap>() {
                    @Override
                    public void call(Subscriber<? super Bitmap> subscriber) {
                        try {
                            String fileNames[] = context.getAssets().list("image/map");
                            InputStream is = context.getAssets().open("image/map/" + fileNames[position]);
                            Bitmap bitmap= BitmapFactory.decodeStream(is);
                            subscriber.onNext(bitmap);
                        } catch (IOException e) {
                            e.printStackTrace();
                            subscriber.onError(e);
                        }
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(action1);
    }

    @Override
    public int loadPosition(String key) {
        QueryBuilder<Setts> equals = new QueryBuilder<>(Setts.class)
                .whereEquals(Setts.COL_KEY, key);
        ArrayList<Setts> list = liteOrm.query(equals);
        Log.i("key: " + key + list);
        if (!list.isEmpty()) {
            return list.get(0).getValueInt();
        }
        return 0;
    }

    @Override
    public void saveMap(Context context, Map map, String name, int position) {
        if (map == null) {
            map = new Map();
            map.setMapMode(Map.MAP_MODE_ASSETS);
        }

        // 名称为空
        if (!name.isEmpty()) {
            map.setName(name);
        }

        try {
            String files[] = context.getAssets().list("image/map");
            map.setMapUrl(files[position]);
            map.setMapSpinner(position);

            liteOrm.save(map);

            Toastor.with(context)
                    .setText("保存成功")
                    .show();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void setDefault(Map map) {
        Setts setts = new Setts(Setts.SETTINGS_MAP_SCENE, map.getId());
        liteOrm.save(setts);
    }

    @Override
    public void getDefaultMap(Subscriber<Number> subscriber) {
        Observable
                .create(new Observable.OnSubscribe<List<Setts>>() {
                    @Override
                    public void call(Subscriber<? super List<Setts>> subscriber) {
                        QueryBuilder<Setts> equals = new QueryBuilder<>(Setts.class)
                                .whereEquals(Setts.COL_KEY, Setts.SETTINGS_MAP_SCENE);
                        ArrayList<Setts> list = liteOrm.query(equals);
                        subscriber.onNext(list);
                    }
                })
                .filter(new Func1<List<Setts>, Boolean>() {
                    @Override
                    public Boolean call(List<Setts> list) {
                        return !list.isEmpty();
                    }
                })
                .map(new Func1<List<Setts>, Number>() {
                    @Override
                    public Number call(List<Setts> list) {
                        return list.get(0).getValueLong();
                    }
                })
                .subscribe(subscriber);
    }

    /*@Override
    public void getDefaultMap(GetOneListener<Number> listener) {
        QueryBuilder<Setts> equals = new QueryBuilder<>(Setts.class)
                .whereEquals(Setts.COL_KEY, Setts.SETTINGS_MAP_SCENE);
        ArrayList<Setts> list = liteOrm.query(equals);
        if (list.isEmpty()) {
            listener.onFailure(0, "Not Found!");
        } else {
            listener.onSuccess(list.get(0).getValueLong());
        }
    }*/

    boolean isFullScreen = false;
    public static final int ANIMATION_FULLSCREEN = 0;
    public static final int ANIMATION_FULLSCREEN_EXIT = 1;
    private int LinearTopHeight = 0;

    @Override
    public int getAnimation() {
        if (!isFullScreen) {
            isFullScreen = true;
            return ANIMATION_FULLSCREEN;
        } else {
            isFullScreen = false;
            return ANIMATION_FULLSCREEN_EXIT;
        }
    }

    @Override
    public int getTopHeight() {
        return LinearTopHeight;
    }

    @Override
    public void setTopHeight(int height) {
        LinearTopHeight = height;
    }

    @Override
    public boolean inputVerify(String num, String mac, String x, String y, String limit, String remark, boolean isShown, Map map) {

        // num编号 x坐标 y坐标 limit限制值 必须都为数字
        if (! (num.matches("[0-9]+") && x.matches("[0-9]+") && y.matches("[0-9]+") && limit.matches("[0-9]+"))) {
            return false;
        }

        // mac 必须为4个16进制字符
        if (!mac.matches("[0-9a-fA-F]{4}")) {
            return false;
        }

        if (map == null) {
            return false;
        }

        return true;
    }

    @Override
    public Station saveStation(String num, String mac, String x, String y, String limit, String remark, boolean isShown, Map map) {
        Station station = new Station();

        station.setNum(Integer.parseInt(num));
        station.setX(Integer.parseInt(x));
        station.setY(Integer.parseInt(y));
        station.setLimit(Integer.parseInt(limit));
        station.setMac(mac);
        station.setRemark(remark);
        station.setShown(isShown);
        station.setMapID(map.getId());

        liteOrm.save(station);
        return station;
    }

    @Override
    public Station updateStation(Station station, String num, String mac, String x, String y, String limit, String remark, boolean isShown, Map map) {
        station.setNum(Integer.parseInt(num));
        station.setX(Integer.parseInt(x));
        station.setY(Integer.parseInt(y));
        station.setLimit(Integer.parseInt(limit));
        station.setMac(mac);
        station.setRemark(remark);
        station.setShown(isShown);
        station.setMapID(map.getId());

        liteOrm.update(station);
        return station;
    }

    @Override
    public void loadStation(final Map map, Subscriber<List<Station>> subscriber) {
        Observable
                .create(new Observable.OnSubscribe<List<Station>>() {
                    @Override
                    public void call(Subscriber<? super List<Station>> subscriber) {
                        QueryBuilder<Station> ss = new QueryBuilder<>(Station.class)
                                .whereEquals(Station.COL_MAP_ID, map.getId());
                        List<Station> ll = liteOrm.query(ss);
                        subscriber.onNext(ll);
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(subscriber);
    }

    @Override
    public void getStation(final Map map, final int position, Subscriber<Station> subscriber) {
        Observable
                .create(new Observable.OnSubscribe<Station>() {
                    @Override
                    public void call(Subscriber<? super Station> subscriber) {
                        QueryBuilder<Station> ss = new QueryBuilder<>(Station.class)
                                .whereEquals(Station.COL_MAP_ID, map.getId());
                        List<Station> ll = liteOrm.query(ss);
                        subscriber.onNext(ll.get(position));
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(subscriber);
    }
}
